import re
from parsedate import find_dates, convert_dates

splitter = re.compile('( |:)')
part_number_regexps = [
    re.compile('[\s(](?:p|pt|part)\s*(\d)'),
    re.compile('[\s(](\d)\s*(?:of|/)\s*[\d]+(?![\d/])'),
]
group_regex = re.compile('(?:grp|group)\s*([a-z]|\d{2})')
versus_regex = re.compile('([a-z0-9\[\]\.\-_\)\!]+)\s+(?:v|v\.|vs|vs\.|versus)\s+([a-z0-9\[\]\.\-_\)\!]+)')
game_number_regexps = [
    re.compile('(?:s|(?:(?:set|game)\s*))\d+'),
    re.compile('\d+set'),
]
number_regexp = re.compile('\d+')

uploaded_formats = ['uploaded: %s', 'uploaded %s', '%s upload']


def parse_info(title, description, author):
    title_info = parse_title(title)
    description_info = parse_description(description)

    info = {
        'author' : author,
    }

    info.update(description_info)
    info.update(title_info)

    if 'participants' not in info:
        info['participants'] = []

    if 'date_played' not in info:
        info['date_played'] = []

    if 'part_number' not in info:
        info['part_number'] = [1]

    if 'game_number' not in info:
        info['game_number'] = []

    return info

def parse_title(title):
    info = {}
    lowered = title.lower()

    title_tokens = split_into_tokens(lowered)

    # Finding league
    leagues = {
        'osl' : 'osl',
        'msl' : 'msl', 'mst' : 'msl',
        'proleague' : 'proleague', 'spl' : 'proleague'
    }

    info['league'] = [leagues[x] for x in leagues if x in title_tokens]

    # Finding league stage
    stages = ['finals', 'semifinals', 'quarterfinals', 'ro4', 'ro8', 'ro16', 'ro36']
    info['league_stage'] = [x for x in stages if x in title_tokens]

    matches = group_regex.findall(lowered)
    if matches:
        info['league_stage'] = ['group-' + x for x in matches]

    # Finding players
    participant_tuples = versus_regex.findall(lowered)

    if participant_tuples:
        info['participants'] = []
        for participant_tuple in participant_tuples:
            info['participants'].append(participant_tuple[0].strip(":"))
            info['participants'].append(participant_tuple[1].strip(":"))


    # Finding game numbers
    numbers = set()
    number_strings = set()
    for regex in game_number_regexps:
        number_strings.update(regex.findall(lowered))

    for number_string in number_strings:
        # Remove the string so the game number isn't accidentally mixed in with
        # dates or other numbers.
        lowered = lowered.replace(number_string, '')
        numbers.update(number_regexp.findall(number_string))

    if numbers:
        info['game_number'] = [int(x) for x in numbers]

    # Finding dates
    date_strings = find_dates(lowered)
    dates = convert_dates(date_strings)
    if dates:
        info['date_played'] = dates

    # Finding part numbers
    numbers = set()
    for regex in part_number_regexps:
        numbers.update(regex.findall(lowered))

    if numbers:
        info['part_number'] = [int(x) for x in numbers]

    return info


def parse_description(description):
    info = {}

    lowered = description.lower()
    description_tokens = split_into_tokens(lowered)

    # Finding dates played
    date_strings = find_dates(lowered)

    # Ignore dates that look like they just are telling us when the video was
    # uploaded.
    real_date_strings = []
    for date in date_strings:
        is_upload_format = False

        for uploaded_format in uploaded_formats:
            uploaded_date = uploaded_format % date

            if uploaded_date in lowered:
                is_upload_format = True

        if not is_upload_format:
            real_date_strings.append(date)

    dates = convert_dates(real_date_strings)

    if dates:
        info['date_played'] = dates

    # Finding map played
    return info

def split_into_tokens(text):
    return [x for x in splitter.split(text) if x not in ' :']

